package demo.dcs.aspect;


import demo.dcs.MertricListener;
import demo.dcs.MertricSendSchedule;
import demo.dcs.vo.XdcsSparkConstant;
import demo.java.lang.management.jvm.AppTraceConfig;
import demo.java.lang.management.vo.MetricSpan;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;


public class GenericObjectPoolListener implements MertricListener {

    private static final Logger logger = LoggerFactory.getLogger(GenericObjectPoolListener.class);

    private GenericObjectPool genericObjectPool;

    private String hostString;

    private int index;

    public GenericObjectPoolListener(GenericObjectPool genericObjectPool, String hostString) {
        this.genericObjectPool = genericObjectPool;
        this.hostString = hostString;
    }

    @Override
    public boolean isDestroyed() {
        return false;
//        return XdcsGenericObjectPoolReflectUtil.isPoolClosed(genericObjectPool);
    }

    @Override
    public boolean isSame(MertricListener listener) {
        if (listener == null)
            return false;
        if (!(listener instanceof GenericObjectPoolListener))
            return false;
        if (((GenericObjectPoolListener) listener).genericObjectPool != this.genericObjectPool)
            return false;
        return true;
    }

    @Override
    public boolean isSameSource(MertricListener listener) {
        if (listener == null || !(listener instanceof GenericObjectPoolListener)) {
            return false;
        }
        GenericObjectPoolListener genericObjectPoolListener = (GenericObjectPoolListener) listener;
        if (StringUtils.equalsIgnoreCase(this.getHostString(), genericObjectPoolListener.getHostString())) {
            return true;
        }
        return false;
    }

    @Override
    public String getMertricListenerType() {

        return "redis-pool1:" + this.getHostString();
    }

    @Override
    public List<MetricSpan> collectMetric() {
        List<MetricSpan> metricSpans = new ArrayList<MetricSpan>();
        if (genericObjectPool == null || StringUtils.isBlank(hostString)) {
            return metricSpans;
        }
        if (isDestroyed()) {
            MertricSendSchedule.getMertricSendSchedule().deleteMertricListener(this);
            return null;
        }

        long timestamp = System.currentTimeMillis();
        MetricSpan metricSpan = new MetricSpan();
        metricSpan.setTimestamp(timestamp);
        metricSpan.setMetric(XdcsSparkConstant.REDIS_DATASOURCE_METRIC);
        metricSpan.getTags().put(XdcsSparkConstant.TAG_APP, AppTraceConfig.getLocalConfig().getAppName());
        metricSpan.getTags().put(XdcsSparkConstant.TAG_IP, AppTraceConfig.getLocalConfig().getIp());
        metricSpan.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_CONNECT, XdcsSparkConstant.TAG_REDIS_NUM_CONNECT);
        metricSpan.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_NAME, hostString);
        metricSpan.getTags().put(XdcsSparkConstant.TAG_REDIS_POOL_INDEX, String.valueOf(index));

        MetricSpan metricSpan1 = new MetricSpan();
        metricSpan1.setTimestamp(timestamp);
        metricSpan1.setMetric(XdcsSparkConstant.REDIS_DATASOURCE_METRIC);
        metricSpan1.getTags().put(XdcsSparkConstant.TAG_APP, AppTraceConfig.getLocalConfig().getAppName());
        metricSpan1.getTags().put(XdcsSparkConstant.TAG_IP, AppTraceConfig.getLocalConfig().getIp());
        metricSpan1.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_CONNECT, XdcsSparkConstant.TAG_REDIS_NUM_BUSY_CONNECT);
        metricSpan1.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_NAME, hostString);
        metricSpan1.getTags().put(XdcsSparkConstant.TAG_REDIS_POOL_INDEX, String.valueOf(index));

        MetricSpan metricSpan2 = new MetricSpan();
        metricSpan2.setMetric(XdcsSparkConstant.REDIS_DATASOURCE_METRIC);
        metricSpan2.getTags().put(XdcsSparkConstant.TAG_APP, AppTraceConfig.getLocalConfig().getAppName());
        metricSpan2.getTags().put(XdcsSparkConstant.TAG_IP, AppTraceConfig.getLocalConfig().getIp());
        metricSpan2.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_CONNECT, XdcsSparkConstant.TAG_REDIS_NUM_IDLE_CONNECT);
        metricSpan2.setTimestamp(timestamp);
        metricSpan2.getTags().put(XdcsSparkConstant.TAG_REDIS_SOURCE_NAME, hostString);
        metricSpan2.getTags().put(XdcsSparkConstant.TAG_REDIS_POOL_INDEX, String.valueOf(index));

        if (genericObjectPool != null) {
            metricSpan.setValue(genericObjectPool.getMaxActive());
            metricSpan1.setValue(genericObjectPool.getNumActive());
            metricSpan2.setValue(genericObjectPool.getNumIdle());
        }
        metricSpans.add(metricSpan);
        metricSpans.add(metricSpan1);
        metricSpans.add(metricSpan2);

        return metricSpans;
    }


    /**
     * @return the hostString
     */
    public String getHostString() {

        return hostString;
    }


    /**
     * @param hostString the hostString to set
     */
    public void setHostString(String hostString) {

        this.hostString = hostString;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}
